import React, { Component } from 'react'

import { connect } from 'dva';
import Link from 'umi/link';
import { Table, Divider, Popconfirm, Badge } from 'antd';

import Form from './components/SearchForm';
import Chart from './components/Chart';
import Ellipsis from '@/components/Ellipsis';

import styled from 'styled-components';
import { UmiComponentProps, BaseComponentProps, Filds } from '@/common/type'
import { checkInit } from '@/utils/util';

const MyLink = styled.span`
  &:hover {
    cursor: pointer;
  }
`

function flatten(arr, result = []) {
  for (let item of arr) {
    if (Array.isArray(item))
      flatten(item, result)
    else
      result.push(item)
  }
  return result
}

const groupBy = (arr, fn) =>
  arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val, i) => {
    acc[val] = (acc[val] || []).concat(arr[i]);
    return acc;
  }, {});

interface IData {
  id: string | number;
  image: string;
  buildName: string;
  floorName: string;
  areaName: string;
  address: string;
  valueMap: {
    voltage?: string;
  }
}

export interface P {
  list?: {
    data: Array<IData>,
    dataCnt: number
  },
  log?: Array<any>;
}

interface State {
  current: number;
  expandedRowKeys: Array<string>;
  time: Array<any>;
  count: Array<any>;
  kind: string;
}

type Props = P & UmiComponentProps & BaseComponentProps;

@connect(({ device_electricity, loading, menu }) => ({
  list: device_electricity.list || {},
  log: device_electricity.log || [],
  dict: device_electricity.dict,
  location: device_electricity.location || [],
  cond: device_electricity.cond || {},
  buttons: menu.buttons,
  loading: loading.effects['device_electricity/queryPage']
}))
class DeviceElectricity extends Component<Props, State> {

  readonly state: State = {
    current: 1,
    time: [],
    count: [],
    expandedRowKeys: [],
    kind: 'leakage',
  };

  componentDidMount() {
    const { dispatch } = this.props;
    checkInit() ? dispatch({ type: `device_electricity/initCond` }) : this.queryData();
  }

  private queryData(offset = 1) {
    const { dispatch } = this.props;

    dispatch({
      type: 'device_electricity/queryPage',
      payload: {
        pageNum: offset
      },
    });
  }

  private initCurrent = () => {
    this.setState({ current: 1 })
  }

  private onShowSizeChange = (current: number, pageSize: number) => {
    const { dispatch, cond } = this.props;
    cond.pageSize = pageSize;
    dispatch({ type: `device_electricity/updateCond`, payload: cond })
  }

  private remove = (id: string | number) => {
    const { dispatch } = this.props;

    this.setState({
      current: 1
    }, () => {
      dispatch({
        type: 'device_electricity/remove',
        payload: id
      })
    })
  }

  private getRange = (data, key, name) => {
    if (!Array.isArray(data.valueRuleList) || !data.valueRuleList) return [];

    const ans = data.valueRuleList[data.valueRuleList.findIndex(u => u.key === key)];
    return ans ? [ans[name[0]], ans[name[1]]] : []
  }

  getAns = (it, time) => {
    let arr = []
    it.forEach(v => {
      const ind = time.indexOf(v.time)
      arr[ind] = v.value
    })
    return arr
  }

  private getValue = (v, key) => {
    return v.valueMap
      ? (Object.keys(v.valueMap)
        .sort()
        .filter(u => u.indexOf(key) === 0)
        .map(w => v.valueMap[w]))
      : '/'
  }

  private open = (record, kind) => {
    const { dispatch } = this.props;

    dispatch({
      type: 'device_electricity/queryLog',
      payload: { deviceId: record.id }
    }).then(() => {
      const { log } = this.props;
      let time = []
      const ans = groupBy(
        flatten(
          log.map(it =>
            Object.keys(it.valueMap)
              .filter(v => v.indexOf(kind) === 0)
              .map(u => {
                time.push(it.createTime ? it.createTime.slice(5) : '')
                return ({ key: u, value: it.valueMap[u], time: it.createTime ? it.createTime.slice(5) : '' })
              })
          )
        ), 'key')

      time = [...new Set(time)]
      const count = Object.values(ans).map((it: Array<{ value: string }>, index) => ({
        name: `${CHART[kind].name}${index + 1}`,
        color: CHART[kind].color[index],
        data: this.getAns(it, time)
      }))
      this.setState({ time, count, kind })
    })

    const { id: key } = record;
    let filtered = this.state.expandedRowKeys;
    if (this.state.expandedRowKeys.includes(key) && this.state.kind === kind) {
      filtered.splice(filtered.findIndex(element => element === key), 1);
    } else {
      filtered = [key];
    }
    this.setState({
      expandedRowKeys: filtered,
    });
  }

  private handleClose = () => {
    this.setState({
      expandedRowKeys: [],
    });
  }

  render() {
    const { buttons } = this.props;
    const { expandedRowKeys, time, count, kind } = this.state;

    const btnList: Filds = {};
    if (Array.isArray(buttons)) {
      buttons.forEach(item => {
        btnList[item.name] = item.name
      });
    }
    const { data = [], dataCnt } = this.props.list;

    const pagination = {
      total: dataCnt,
      showTotal: (total: number) => `共 ${total} 条`,
      current: this.state.current,
      pageSizeOptions: ['10', '20', '50', '100'],
      onShowSizeChange: this.onShowSizeChange,
      showSizeChanger: true,
      onChange: (current: number) => {
        this.setState({ current }, () => this.queryData(current));
      },
    };

    const columns: any = [{
      title: '系统编号',
      dataIndex: 'systemNo',
    },{
      title: '设备名称',
      dataIndex: 'name',
    }, {
      title: '安装地址',
      dataIndex: 'installationAddr',
      render: (text, record) => (
        <Ellipsis tooltip={true} lines={1}>
          {record.buildName || ''}{record.floorName || ''}{record.areaName || ''}{text || ''}
        </Ellipsis>
      )
    }, {
      title: 'IMEI码',
      dataIndex: 'networkAddr',
    }, {
      title: '联网状态',
      dataIndex: 'runStatus',
      render: (text, record) => (
        <>
          <Badge status={+text === 1 ? "success" : 'error'} />
          <span>{record.runStatusName}</span>
        </>
      )
    }, {
      title: '电压/ V',
      dataIndex: 'voltage',
      render: (text, record) => (
        <>
          {
            Array.isArray(text)
              ? text.map((v, index) =>
                <MyLink
                  onClick={() => this.open(record, 'voltage')}
                  key={index} style={{color: 'var(--primary-blue)'}}
                >{index === 0 ? `${v || 0}V` : `/${v || 0}V`}</MyLink>)
              : '/'
          }
        </>
      )
    },{
      title: '电流/A',
      dataIndex: 'ampere',
      render: (text, record) => (
        <>
          {
            Array.isArray(text)
              ? text.map((v, index) =>
                <MyLink
                  onClick={() => this.open(record, 'ampere')}
                  key={index} style={{color: 'var(--primary-blue)'}}
                >{index === 0 ? `${v || 0}A` : `/${v || 0}A`}</MyLink>)
              : '/'
          }
        </>
      )
    }, {
      title: '剩余电流/mA',
      dataIndex: 'leakage',
      render: (text, record) => (
        <>
          {
            Array.isArray(text)
              ? text.map((v, index) =>
                <MyLink
                  onClick={() => this.open(record, 'leakage')}
                  key={index} style={{
                    color: (record.lEArr && v >= record.lEArr[1])
                      ? '#e96201'
                      : 'var(--primary-blue)'
                  }}
                >{index === 0 ? `${v || 0}mA` : `/${v || 0}mA`}</MyLink>)
              : '/'
          }
        </>
      )
    }, {
      title: '温度/ ℃',
      dataIndex: 'temperature',
      render: (text, record) => (
        <>
          {
            Array.isArray(text)
              ? text.map((v, index) =>
                <MyLink
                  onClick={() => this.open(record, 'temperature')}
                  key={index} style={{
                    color: (record.tEArr && (v >= record.tEArr[1]))
                      ? '#e96201'
                      : 'var(--primary-blue)'
                  }}
                >{index === 0 ? `${v || 0}℃` : `/${v || 0}℃`}</MyLink>)
              : '/'
          }
        </>
      )
    }, {
      title: '操作', key: 'x',
      render: (record: IData, text: number | string, index: number) => {
        return (
          <div style={{ display: 'flex' }}>
            <>
              <Link to={`/data/device_electricity/${record.id}/update`}>编辑</Link>
              <Divider type="vertical" />
            </>
            {/* <Popconfirm
              title="请确认是否删除?"
              onConfirm={() => this.remove(record.id)} okText="确定" cancelText="取消"
            >
              <a>删除</a>
            </Popconfirm> */}
          </div>
        )
      }
    }];

    const ans = Array.isArray(data) ? data.map((v, index) => ({
      ...v,
      ind: index + 1 < 10 ? `0${index + 1}` : index + 1,
      leakage: this.getValue(v, 'leakage'),
      temperature: this.getValue(v, 'temperature'),
      ampere: this.getValue(v, 'ampere'),
      voltage: this.getValue(v, 'voltage'),
      tEArr: this.getRange(v, 'temperature', ['alarmLowerValue', 'alarmUpperValue']),
      lEArr: this.getRange(v, 'leakage', ['minValue', 'maxValue']),
    })) : []

    return (
      <>
        <Form current={this.state.current} initCurrent={this.initCurrent} new={!!btnList['新增']} />
        <Table
          columns={[{
            title: '序号',
            dataIndex: 'ind',
          }, ...columns]}
          pagination={pagination}
          dataSource={ans}
          bordered
          expandedRowRender={
            record => expandedRowKeys.length > 0 
              ? <Chart close={this.handleClose} time={time} count={count} styles={CHART[kind].styles || {}} /> 
              : <></>
          }
          expandIcon={() => ''}
          loading={this.props.loading}
          expandedRowKeys={expandedRowKeys}
          rowKey="id"
        />
      </>
    );
  }
}

export default DeviceElectricity;


const CHART = {
  'ampere': {
    name: '电流',
    color: ['#0880DF', '#3D9B38', '#ED7109', '#E61219'],
    styles: {
      titleY: 'A',
      titleX: '时间',
      boundaryGap: false,
    }
  },
  'temperature': {
    name: '温度',
    color: ['#0880DF', '#3D9B38', '#ED7109', '#E61219'],
    styles: {
      titleY: '℃',
      titleX: '时间',
      boundaryGap: false,
    }
  },
  'voltage': {
    name: '电压',
    color: ['#0880DF', '#3D9B38', '#ED7109', '#E61219'],
    styles: {
      titleY: 'V',
      titleX: '时间',
      boundaryGap: false,
    }
  },
  'leakage': {
    name: '剩余电流',
    color: ['#0880DF', '#3D9B38', '#ED7109', '#E61219'],
    styles: {
      titleY: 'mA',
      titleX: '时间',
      boundaryGap: false,
    }
  },
}